﻿# -*- coding: utf-8 -*-
#
# Copyright 2008 Yejun Yang
#
import random
import utils
utils.dummify_beaker()

from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.api import users

import logging

class Handler(webapp.RequestHandler):
    """Extended Request Handler"""
    
    _count = 0
    
    count = property(lambda self: Handler._count)
    app = property(lambda self: Application._instance)
    appid = property(lambda self: Application._uid)
    
    is_secure = property(lambda self: self.request.environ.get("HTTPS",'off').lower() in ('yes','on','1'))
    is_dev = property(lambda self: self.request.environ.get('SERVER_SOFTWARE','').lower().startswith('dev'))
    is_external = property(lambda self: bool(self.request.referer and not self.request.referer.startswith(self.request.host_url)))
    is_admin = property(lambda self: is_current_user_admin())
    
    domain = property(lambda self: self.request.environ.get('AUTH_DOMAIN','gmail.com'))
    user = property(lambda self: users.get_current_user())
    login_url = property(lambda self: users.create_login_url(self.request.url))
    logout_url = property(lambda self: users.create_logout_url(self.request.url))
    
    def __new__(cls):
        Handler._count += 1
        return super(Handler, cls).__new__(cls)
        
    def __init__(self):
        webapp.RequestHandler.__init__(self)
        self.uid = self.appid + self.count

    def __hash__(self):
        return self.uid
        
    def handle_exception(self, exception, debug_mode):
        out = self.response.out.getvalue()
        self.error(500)
        import traceback, sys
        lines = ''.join(traceback.format_exception(*sys.exc_info()))
        logging.error(lines)
        if debug_mode:
            from errors import render_error
            self.response.out.write(render_error(self, out))
            
    def error(self, code):
        method = "error_%d" % code
        if method in self.__class__.__dict__ and callable(self.__class__.__dict__[method]):
            self.__class__.__dict__[method](self)
        else:
            webapp.RequestHandler.error(self, code)
             
class Application(webapp.WSGIApplication):
    """WSGI Application"""
    
    run = run_wsgi_app
    
    _instance = None
    
    _uid = 0
    
    def __new__(cls, url_mapping, debug=False):
        if Application._instance is None:
            Application._instance = super(Application, cls).__new__(cls, url_mapping, debug)
        return Application._instance
        
    def __init__(self, url_mapping, debug):
        if Application._uid: return
        Application._uid = random.randint(100000000000000000L, 999999999900000000L)
        webapp.WSGIApplication.__init__(self, url_mapping, debug)
        logging.info("New application is created with id %d at %s" % (Application._uid, hex(id(self))))

    def profile_run(self,detail=False):
        import cProfile, pstats, cStringIO, logging
        prof = cProfile.Profile()
        prof = prof.runctx("self.run()", globals(), locals())
        out = cStringIO.StringIO()
        stats = pstats.Stats(prof)
        stats.stream = out
        stats.sort_stats("time")  # Or cumulative
        stats.print_stats(20)  # 80 = how many to print
        if detail:
            stats.print_callees()
            stats.print_callers()
        logging.info(out.getvalue())
        
    
class SimpleHandler(Handler):
    """A simple handler which takes the first paramenter from 
    url mapping as method name. 
    post will be handled as get.
    """
    def get(self, name, *args):
        name = name.lower().strip('/').replace('/','_').replace('.','_')
        if name in self.__class__.__dict__ and callable(self.__class__.__dict__[name]):
            return self.__class__.__dict__[name](self, *args)
        self.error(404)
        
    post = get
            
       
        
  